import datetime
import os
import time
import traceback
import random
import base64
import json

import requests
from loguru import logger
import numpy
import zipfile
import hashlib


class KS_BILL:
    def __init__(self, playwright, host, app_id):
        self.app_id = app_id
        self.secret = "P4I8HCOP1OP7432XZVKR2MPJKKVQ7J"
        self.playwright = playwright
        self.host = host
        self.context = None
        self.browser = None
        self.page = None
        self.index_url = "https://s.kwaixiaodian.com/"
        self.bill_download_path = os.path.join(os.getcwd(), 'ksBill')
        if not os.path.exists(self.bill_download_path):
            os.makedirs(self.bill_download_path)
        self.tj_account = self.get_tujian_account()

    def login(self, store):
        browser = self.playwright.chromium.launch(headless=False)
        self.context = browser.new_context(accept_downloads=True)
        self.page = self.context.new_page()
        self.page.goto(self.index_url, timeout=20000)
        self.wait(self.page)
        for c in range(20):
            try:
                if self.page.query_selector('span:text-is("我是员工")') is not None:
                    break
            except:
                pass
            time.sleep(1)
        self.page.query_selector('span:text-is("我是员工")').click()
        time.sleep(1)
        self.page.query_selector('span:text-is("密码登录")').click()
        self.page.query_selector('input[placeholder="请输入手机号"]').fill(store['userName'])
        self.page.query_selector('input[placeholder="请输入密码"]').fill(store['pwd'])
        time.sleep(1)
        logger.info('点击登录')
        self.page.query_selector('button:has-text("登录")').click()
        time.sleep(3)
        # 处理短信验证码
        self.set_sms_code(store['mobile'])
        for i in range(20):
            try:
                if self.page.query_selector('input[placeholder="打单发货"]:visible') is not None or self.page.query_selector('input[placeholder="请输入账号名或店铺名搜索"]:visible') is not None:
                    logger.info('登录成功')
                    break
            except:
                pass
            time.sleep(1)
            logger.info(f'等待页面加载【{i+1}】秒...')
        for c in range(3):
            self.close_dialog()
        self.check_slide_code()

    def choice_store(self, store):
        logger.info('检查是否需要选择店铺')
        need_choice = False
        for c in range(5):
            try:
                if self.page.query_selector('input[placeholder="请输入账号名或店铺名搜索"]:visible') is not None:
                    need_choice = True
                    break
            except:
                pass
            time.sleep(1)
        logger.info(f'检查结果：【{need_choice}】')
        if need_choice:
            if self.page.query_selector(f'div:text-is("{store["account"]}"):visible') is None:
                logger.info(f'找不到店铺【{store["account"]}】')
                return False, f'找不到店铺【{store["account"]}】'
            self.page.query_selector(f'div:text-is("{store["account"]}"):visible').click()
            time.sleep(2)
            self.set_sms_code(store['mobile'])
            for c in range(3):
                self.close_dialog()
        return True, None

    def check_store_id(self, shop_id):
        for c in range(20):
            try:
                if self.page.query_selector('div.seller-main-space-item') is not None:
                    break
            except:
                pass
            time.sleep(1)
        div_list = self.page.query_selector_all('div.seller-main-space-item >> div >> div')
        id_text = None
        for div in div_list:
            id_text = div.text_content()
            if 'ID:' in id_text:
                break
        if id_text is None:
            raise Exception('店铺ID验证失败')
        sys_shop_id = id_text.split(':')[1]
        if sys_shop_id != shop_id:
            logger.info(f'店铺ID【{shop_id}】与官方店铺ID【{sys_shop_id}】不匹配')
            return False, f'店铺ID【{shop_id}】与官方店铺ID【{sys_shop_id}】不匹配'
        if sys_shop_id == shop_id:
            logger.info('验证店铺ID通过')
            return True, None


    # 输入手机验证码
    def set_sms_code(self, mobile):
        has_sms = False
        sms_frame = None
        for c in range(5):
            try:
                logger.info(f'正在检查是否需要手机验证码【{c + 1}】秒')
                self.page.query_selector('div')
                sms_frame = self.page.frame(url='https://app.m.kuaishou.com/zt/unified/tools/verification/verify-sms-unified?*')
                if sms_frame is not None:
                    has_sms = True
                    break
            except:
                pass
            time.sleep(1)
        logger.info(f'检查结果：【{has_sms}】')
        if has_sms:
            sms_frame.query_selector('span:has-text("获取验证码")').click()
            time.sleep(30)
            sms_text = self.get_sms_code(mobile)
            if '快手科技' not in sms_text:
                logger.info('获取验证码失败')
                raise Exception('获取验证码失败')
            # 验证码示例：【快手科技】快手验证码：123456 ，15分钟内有效，仅限于本人使用，切勿告知他人！
            sms_code = sms_text.split('：')[1].split('，')[0]
            sms_frame.query_selector('input[placeholder="请输入验证码"]').fill(sms_code)
            time.sleep(1)
            sms_frame.query_selector('button:has-text("确定")').click()

    # 获取手机验证码
    def get_sms_code(self, mobile):
        for t in range(3):
            try:
                res = requests.get('http://1.95.166.150:8997/api/v1/sms/info/'+mobile)
                logger.info(f'获取手机验证码结果：{res.text}')
                sms_text = res.json()['data']
                if sms_text is not None and '快手科技' in sms_text:
                    return sms_text
                time.sleep(3)
            except:
                logger.info(traceback.format_exc())
        return ''

    def ease_out_quart(self, x):
        return 1 - pow(1 - x, 4)

    def get_tracks(self, distance, seconds, ease_func):
        distance += 0
        tracks = [0]
        offsets = [0]
        for t in numpy.arange(0.0, seconds, 0.1):
            ease = ease_func
            offset = round(ease(t / seconds) * distance)
            tracks.append(offset - offsets[-1])
            offsets.append(offset)
        tracks.extend([-3, -2, -3, -2, -2, -2, -2, -1, -0, -1, -1, -1])
        return tracks

    def move_to_gap(self, page, ix, iy, track):
        """
        慢速移动鼠标
        :param ix:
        :param iy:
        :param track:
        :return:
        """
        f_y = [10, 12, 4, 6, 8, -4, -6, -8]
        t_list = [0.1, 0.2, 0.3, 0.4, 0.5]
        mx = ix
        while track:
            x = track.pop(0)
            mx = mx + x
            page.mouse.move(mx, iy + random.choice(f_y))
            time.sleep(random.choice(t_list))
        page.mouse.up()

    def get_slider_xy(self, backImgPath):
        api = 'http://api.ttshitu.com/base64'
        with open(backImgPath, 'rb') as f:
            base64_data = base64.b64encode(f.read())
            b642 = base64_data.decode()
        params = {"typeid": "33", "image": b642, "username": self.tj_account['tjName'], "password": self.tj_account['tjPass']}
        headers = {'content-type': 'application/json;charset=UTF-8'}
        result = json.loads(requests.post(api, json=params, headers=headers).text)
        if result['success']:
            return result["data"]["result"]
        else:
            logger.info(result["message"])
            return result["data"]

    def close_dialog(self):
        for c in range(3):
            if self.page.query_selector('button:has-text("跳过"):visible') is not None:
                try:
                    self.page.query_selector('button:has-text("跳过"):visible').click(timeout=3000)
                    break
                except:
                    pass
                time.sleep(1)
        btn_list = self.page.query_selector_all('button:has-text("关闭"):visible')
        for btn in btn_list:
            try:
                btn.click(timeout=3000)
            except:
                pass
            time.sleep(1)
        for c in range(3):
            if self.page.query_selector('#driver-page-overlay:visible') is not None:
                try:
                    self.page.query_selector('#driver-page-overlay:visible').click(timeout=3000)
                except:
                    pass
                time.sleep(1)
        btn_list = self.page.query_selector_all('button:has-text("我知道了"):visible')
        for btn in btn_list:
            try:
                btn.click(timeout=3000)
            except:
                pass
            time.sleep(1)
        btn_list = self.page.query_selector_all('span:has-text("关闭"):visible')
        for btn in btn_list:
            try:
                btn.click(timeout=3000)
            except:
                pass
            time.sleep(1)
        for c in range(3):
            try:
                if self.page.query_selector('svg[data-icon="system-error-circle-line"]:visible') is not None:
                    self.page.query_selector('svg[data-icon="system-error-circle-line"]:visible').click(timeout=3000)
                    break
            except:
                pass
            time.sleep(1)
        btn_list = self.page.query_selector_all('button:has-text("暂不处理"):visible')
        for c in range(3):
            for btn in btn_list:
                try:
                    btn.click(timeout=3000)
                except:
                    pass
                time.sleep(1)
        btn_list = self.page.query_selector_all('button:has-text("取消"):visible')
        logger.info('共' + str(len(btn_list)) + '个取消按钮')
        for btn in btn_list:
            try:
                btn.click(timeout=3000)
            except:
                pass
            time.sleep(1)

    def download_bill_file(self, store, yesterday):
        # self.page.query_selector('#main-pc-page-layout >> span.seller-main-badge >> span:text-is("资金")').click()
        # time.sleep(2)
        # self.page.query_selector('#main-pc-page-layout >> span.seller-main-badge >> span:text-is("结算账单")').click()
        self.page.goto("https://s.kwaixiaodian.com/zone/fund/accounting/payment-bill")
        logger.info('跳转到【结算账单】页面...')
        self.wait(self.page)
        for i in range(20):
            try:
                if self.page.query_selector('input[placeholder="开始日期"]:visible') is not None:
                    break
            except:
                pass
            time.sleep(1)
            logger.info(f'等待页面加载【{i+1}】秒...')
        self.page.query_selector('input[placeholder="开始日期"]:visible').click()
        time.sleep(1)
        self.page.query_selector('input[placeholder="开始日期"]:visible').fill(f'{yesterday} 00:00:00')
        time.sleep(1)
        self.page.query_selector('div.zone-fund-accounting-picker-range-wrapper:visible >> button:has-text("确 定")').click()
        time.sleep(1)
        self.page.query_selector('input[placeholder="结束日期"]:visible').click()
        time.sleep(1)
        self.page.query_selector('input[placeholder="结束日期"]:visible').fill(f'{yesterday} 23:59:59')
        time.sleep(1)
        self.page.query_selector('div.zone-fund-accounting-picker-range-wrapper:visible >> button:has-text("确 定")').click()
        time.sleep(1)
        logger.info('点击【查询】...')
        self.page.query_selector('button:has-text("查 询")').click()
        time.sleep(1)
        with self.page.expect_response('https://s.kwaixiaodian.com/rest/app/tts/business/api/funds/financial/bill/pcpageorder/list') as response_info:
            self.page.query_selector('button:has-text("查 询")').click()
        response = response_info.value
        self.wait(self.page)
        if response.status == 200:
            total = response.json()['data']['total']
            if total > 0:
                logger.info(f'查询到【{total}】条数据...')
            else:
                logger.info('暂无数据')
                return None
        else:
            logger.info('查询失败')
            raise Exception("查询失败")
        self.page.query_selector('button:has-text("导 出")').click()
        time.sleep(3)
        for c in range(3):
            try:
                if self.page.query_selector('button:has-text("知道了"):visible') is not None:
                    self.page.query_selector('button:has-text("知道了"):visible').click()
                    break
            except:
                pass
            time.sleep(1)
        time.sleep(3)
        self.page.query_selector('button:has-text("查看导出记录")').click()
        self.wait(self.page)
        for c in range(20):
            try:
                if self.page.query_selector('div.zone-fund-accounting-descriptions') is not None and len(self.page.query_selector_all('div.zone-fund-accounting-descriptions')) > 0:
                    break
            except:
                pass
            logger.info('等待页面加载...')
            time.sleep(1)
        rows = self.page.query_selector_all('div.zone-fund-accounting-descriptions')
        row_index = -1
        for index, row in enumerate(rows):
            search_time = row.query_selector('div.zone-fund-accounting-descriptions-item-container:has(span:has-text("结算时间")) >> span.zone-fund-accounting-descriptions-item-content').text_content()
            if search_time.strip() == f'{yesterday} 00:00:00 - {yesterday} 23:59:59':
                row_index = index
                break
        if row_index == -1:
            raise Exception("下载失败")
        for t in range(60):
            if self.page.query_selector(f'div.zone-fund-accounting-descriptions >> nth={row_index}').query_selector('button:has-text("下 载"):visible') is not None:
                break
            logger.info(f'等待下载按钮【{t + 1}】秒')
            time.sleep(1)
        with self.page.expect_download() as download_info:
            self.page.query_selector(f'div.zone-fund-accounting-descriptions >> nth={row_index}').query_selector('button:has-text("下 载")').click()
        download_obj = download_info.value
        file_path = os.path.join(self.bill_download_path, f'ksBill-{store["platformStoreName"]}-{yesterday}-{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}.zip')
        # 删除旧文件
        if os.path.exists(file_path):
            os.remove(file_path)
        download_obj.save_as(file_path)
        # 等待文件下载完成
        for i in range(60):
            if os.path.exists(file_path):
                break
            time.sleep(1)
        if not os.path.exists(file_path):
            raise Exception(f"【{file_path}】下载失败")
        logger.info(f"【{file_path}】下载成功")
        bill_path = self.get_bill_file(file_path, yesterday)
        logger.info(f'快手结算账单文件路径：{bill_path}')
        return bill_path

    def get_bill_count(self, period):
        # self.page.query_selector('#main-pc-page-layout >> span.seller-main-badge >> span:text-is("资金")').click()
        # time.sleep(2)
        # self.page.query_selector('#main-pc-page-layout >> span.seller-main-badge >> span:text-is("结算账单")').click()
        self.page.goto("https://s.kwaixiaodian.com/zone/fund/accounting/payment-bill")
        logger.info('跳转到【结算账单】页面...')
        self.wait(self.page)
        for i in range(20):
            try:
                if self.page.query_selector('input[placeholder="开始日期"]:visible') is not None:
                    break
            except:
                pass
            time.sleep(1)
            logger.info(f'等待页面加载【{i + 1}】秒...')
        self.page.query_selector('input[placeholder="开始日期"]:visible').click()
        time.sleep(1)
        start_date = period + '-01'
        self.page.query_selector('input[placeholder="开始日期"]:visible').fill(f'{start_date} 00:00:00')
        time.sleep(1)
        self.page.query_selector('div.zone-fund-accounting-picker-range-wrapper:visible >> button:has-text("确 定")').click()
        time.sleep(1)
        self.page.query_selector('input[placeholder="结束日期"]:visible').click()
        time.sleep(1)
        end_date = ((datetime.datetime.strptime(start_date, '%Y-%m-%d') + datetime.timedelta(days=31)).replace(day=1) - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
        self.page.query_selector('input[placeholder="结束日期"]:visible').fill(f'{end_date} 23:59:59')
        time.sleep(1)
        self.page.query_selector('div.zone-fund-accounting-picker-range-wrapper:visible >> button:has-text("确 定")').click()
        time.sleep(1)
        logger.info('点击【查询】...')
        self.page.query_selector('button:has-text("查 询")').click()
        time.sleep(1)
        with self.page.expect_response('https://s.kwaixiaodian.com/rest/app/tts/business/api/funds/financial/bill/pcpageorder/list') as response_info:
            self.page.query_selector('button:has-text("查 询")').click()
        response = response_info.value
        self.wait(self.page)
        if response.status == 200:
            total = response.json()['data']['total']
            return total
        else:
            logger.info('查询失败')
            raise Exception("查询失败")

    def check_slide_code(self):
        code_frame = None
        for c in range(10):
            try:
                self.page.query_selector('div')
                code_frame = self.page.frame(url='https://captcha.zt.kuaishou.com/iframe/index.html?*')
                if code_frame is not None:
                    logger.info('出现滑动验证码')
                    break
            except:
                pass
            time.sleep(1)
            logger.info(f'正在检查是否有滑动验证码【{c+1}】秒')
        if code_frame is not None:
            code_frame.query_selector('div.icon-close').click()
            return
            # code_path = os.path.join(os.getcwd(), 'code.png')
            # for k in range(20):
            #     try:
            #         if code_frame.query_selector('img.bg-img') is None:
            #             break
            #         code_frame.query_selector('img.bg-img').screenshot(path=code_path)
            #         time.sleep(0.5)
            #         dist = int(self.get_slider_xy(code_path))
            #         box = code_frame.query_selector('div.slider-btn').bounding_box()
            #         track = self.get_tracks(dist+10, 1, self.ease_out_quart)
            #         ix = int(box['x'] + box['width'] // 2)
            #         iy = int(box['y'] + box['height'] // 2)
            #         self.page.mouse.move(ix, iy)
            #         self.page.mouse.down(button='left')
            #         self.move_to_gap(self.page, ix, iy, track)
            #         time.sleep(1.5)
            #         logger.info("滑动完成...")
            #         time.sleep(5)
            #     except:
            #         pass


    def get_bill_file(self, file_path, last_month):
        # 删除旧文件
        path = os.path.join(self.bill_download_path, last_month)
        file_list = []
        self.get_all_files(path, file_list)
        for file in file_list:
            os.remove(file)
        # 解压文件
        self.unzip(file_path, path)
        bill_path = None
        for file in os.listdir(path):
            bill_path = os.path.join(path, file)
        return bill_path

    def get_all_files(self, path, file_list):
        if not os.path.exists(path):
            return
        for file in os.listdir(path):
            if os.path.isfile(os.path.join(path, file)):
                file_list.append(os.path.join(path, file))
            else:
                self.get_all_files(os.path.join(path, file), file_list)

    def get_store_account(self, platform, type):
        timestamp = int(time.time() * 1000)
        text = "{}{}{}".format(self.app_id, timestamp, self.secret)
        sign = hashlib.md5(text.encode(encoding='UTF-8')).hexdigest()
        url = self.host + f"api/v1/storeAccount/getAccountList/{platform}?appId={self.app_id}&type={type}&sign={sign.upper()}&timestamp={timestamp}"
        logger.info(url)
        res = requests.get(url)
        logger.info(f'获取店铺账号结果：{res.text}')
        if res.status_code == 200:
            return res.json()['data']

    # 获取图鉴账号密码
    def get_tujian_account(self):
        timestamp = int(time.time() * 1000)
        text = "{}{}{}".format(self.app_id, timestamp, self.secret)
        sign = hashlib.md5(text.encode(encoding='UTF-8')).hexdigest()
        url = self.host + f"api/v1/tjAccount/findOne?appId={self.app_id}&sign={sign.upper()}&timestamp={timestamp}"
        res = requests.get(url)
        if res.status_code == 200:
            return res.json()['data']

    def wait(self, page, seconds=1):
        try:
            page.wait_for_load_state(state="domcontentloaded")
            time.sleep(seconds)
        except:
            pass

    def upload_file(self, api_url, coding_param, file_list):
        try:
            timestamp = int(time.time() * 1000)
            text = "{}{}{}".format(self.app_id, timestamp, self.secret)
            sign = hashlib.md5(text.encode(encoding='UTF-8')).hexdigest()
            logger.info("正在上传文件到服务器")
            url = self.host + api_url + f"?appId={self.app_id}&sign={sign.upper()}&timestamp={timestamp}"
            files = []
            for file in file_list:
                files.append(('file', (open(file, 'rb'))))
            logger.info(f'上传文件到服务器url：{url}')
            response = requests.request("POST", url, files=files, headers={'codingParam': coding_param}, timeout=180)
            logger.info('上传文件到服务器结果：' + response.text)
        except:
            logger.info(traceback.format_exc())

    def encode_param(self, data_list):
        timestamp = int(time.time() * 1000)
        text = "{}{}{}".format(self.app_id, timestamp, self.secret)
        sign = hashlib.md5(text.encode(encoding='UTF-8')).hexdigest()
        url = self.host + f"api/v1/storeAccount/codingParams?appId={self.app_id}&sign={sign.upper()}&timestamp={timestamp}"
        res = requests.post(url, data=json.dumps(data_list), headers={'content-type': 'application/json'})
        if res.status_code == 200:
            return res.json()['data']

    def close(self):
        try:
            if self.page:
                self.page.close()
        except:
            pass
        try:
            if self.browser:
                self.browser.close()
        except:
            pass
        try:
            if self.context:
                self.context.close()
        except:
            pass

    def download_delivery_fee(self, store, yesterday):
        self.page.goto('https://s.kwaixiaodian.com/zone/insurance/freight/index')
        # self.page.query_selector('#main-pc-page-layout >> span.seller-main-badge >> span:text-is("售后")').click()
        # time.sleep(2)
        # for c in range(3):
        #     try:
        #         btn_list = self.page.query_selector_all('button:has-text("我知道了"):visible')
        #         for btn in btn_list:
        #             btn.click()
        #     except:
        #         pass
        #     time.sleep(10)
        # for k in range(3):
        #     for c in range(5):
        #         try:
        #             if self.page.query_selector('button:text-is("关闭"):visible') is not None:
        #                 self.page.query_selector('button:text-is("关闭"):visible').click(timeout=3000)
        #                 break
        #         except:
        #             pass
        #         time.sleep(1)
        # self.page.query_selector('#main-pc-page-layout >> span.seller-main-badge >> span:text-is("退货补运费")').click()
        logger.info('跳转到【退货补运费】页面...')
        self.wait(self.page)
        for c in range(5):
            try:
                if self.page.query_selector('button:text-is("关闭"):visible') is not None:
                    self.page.query_selector('button:text-is("关闭"):visible').click(timeout=3000)
                    break
            except:
                pass
            time.sleep(1)
        for c in range(3):
            try:
                btn_list = self.page.query_selector_all('button:has-text("我知道了"):visible')
                for btn in btn_list:
                    btn.click()
            except:
                pass
            time.sleep(10)
        for i in range(20):
            try:
                if self.page.query_selector('div:text-is("服务记录"):visible') is not None:
                    break
            except:
                pass
            time.sleep(1)
            logger.info(f'等待页面加载【{i + 1}】秒...')
        time.sleep(3)
        if self.page.query_selector('div.FreightInsuranceGuideTitleV2:visible') is not None:
            logger.info('没有权限查询运费险')
            return False, '没有权限查询运费险'
        for c in range(5):
            try:
                if self.page.query_selector('div.kwaishop-seller-insurance-pc-modal:visible') is not None:
                    self.page.query_selector('span.kwaishop-seller-insurance-pc-modal-close-x:visible').click()
                    break
            except:
                pass
            time.sleep(1)
        time.sleep(2)
        self.page.query_selector('div:text-is("服务记录")').click()
        for i in range(20):
            try:
                if self.page.query_selector('label[title="生效时间"]:visible') is not None:
                    break
            except:
                pass
            time.sleep(1)
            logger.info(f'等待页面加载【{i + 1}】秒...')
        # self.page.query_selector('span:text-is("退货补运费服务记录")').click()
        time.sleep(0.5)
        for i in range(6):
            self.page.keyboard.press("ArrowDown")
            time.sleep(0.3)
        self.page.query_selector('input[placeholder="开始日期"]:visible').click()
        time.sleep(1)
        self.page.query_selector('input[placeholder="开始日期"]:visible').fill(f'{yesterday} 00:00:00')
        time.sleep(1)
        self.page.query_selector('div.kwaishop-seller-insurance-pc-picker-dropdown:visible >> button:has-text("确 定")').click()
        time.sleep(1)
        self.page.query_selector('input[placeholder="结束日期"]:visible').click()
        time.sleep(1)
        self.page.query_selector('input[placeholder="结束日期"]:visible').fill(f'{yesterday} 23:59:59')
        time.sleep(1)
        self.page.query_selector('div.kwaishop-seller-insurance-pc-picker-dropdown:visible >> button:has-text("确 定")').click()
        time.sleep(1)
        logger.info('点击【查询】...')
        with self.page.expect_response('https://s.kwaixiaodian.com/gateway/privileges/insurance/b/pc/backend/listView') as response_info:
            self.page.query_selector('button:has-text("查 询")').click()
        response = response_info.value
        self.wait(self.page)
        if response.status != 200:
            logger.info('查询失败')
            raise Exception("查询失败")
        time.sleep(3)
        if self.page.query_selector('li.kwaishop-seller-insurance-pc-pagination-total-text') is None:
            logger.info('暂无数据')
            return True, None
        page_text = self.page.query_selector('li.kwaishop-seller-insurance-pc-pagination-total-text').text_content()
        logger.info(page_text)
        time.sleep(2)
        self.page.query_selector('button:has-text("批量导出")').click()
        time.sleep(3)
        with self.page.expect_popup() as popup_info:
            self.page.query_selector('div.kwaishop-seller-insurance-pc-modal-content >> button:has-text("生成报表")').click()
        new_page = popup_info.value
        self.wait(new_page)
        for k in range(60):
            for c in range(20):
                try:
                    if new_page.query_selector('div.kwaishop-seller-insurance-pc-table-content >> table') is not None:
                        break
                except:
                    pass
                logger.info('等待页面加载...')
                time.sleep(1)
            time.sleep(3)
            rows = new_page.query_selector_all('div.kwaishop-seller-insurance-pc-table-content >> table >> tbody >> tr')
            row_index = -1
            for index, row in enumerate(rows):
                search_time = row.query_selector('td >> nth=2').text_content()
                if search_time.strip() == f'{yesterday} 00:00:00 - {yesterday} 23:59:59':
                    row_index = index
                    break
            if row_index == -1:
                raise Exception("下载失败")
            logger.info('检查下载状态')
            status = new_page.query_selector(f'div.kwaishop-seller-insurance-pc-table-content >> table >> tbody >> tr >> nth={row_index} >> td >> nth=3').text_content()
            logger.info(f'状态【{status}】')
            if '处理成功' != status:
                time.sleep(5)
                new_page.reload()
                continue
            break
        if '处理成功' != status:
            raise Exception("下载失败")
        with new_page.expect_download() as download_info:
            new_page.query_selector(f'div.kwaishop-seller-insurance-pc-table-content >> table >> tbody >> tr >> nth={row_index} >> button:has-text("下载")').click()
        download_obj = download_info.value
        file_path = os.path.join(self.bill_download_path, f'ksBill-{store["platformStoreName"]}-{yesterday}-{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}.xlsx')
        # 删除旧文件
        if os.path.exists(file_path):
            os.remove(file_path)
        download_obj.save_as(file_path)
        # 等待文件下载完成
        for i in range(60):
            if os.path.exists(file_path):
                break
            time.sleep(1)
        if not os.path.exists(file_path):
            raise Exception(f"【{file_path}】下载失败")
        logger.info(f"【{file_path}】下载成功")
        new_page.close()
        return True, file_path

    def get_delivery_fee_count(self, period):
        self.page.goto('https://s.kwaixiaodian.com/zone/insurance/freight/index')
        # self.page.query_selector('#main-pc-page-layout >> span.seller-main-badge >> span:text-is("售后")').click()
        # time.sleep(2)
        # for c in range(3):
        #     try:
        #         btn_list = self.page.query_selector_all('button:has-text("我知道了"):visible')
        #         for btn in btn_list:
        #             btn.click()
        #     except:
        #         pass
        #     time.sleep(10)
        # for k in range(3):
        #     for c in range(5):
        #         try:
        #             if self.page.query_selector('button:text-is("关闭"):visible') is not None:
        #                 self.page.query_selector('button:text-is("关闭"):visible').click(timeout=3000)
        #                 break
        #         except:
        #             pass
        #         time.sleep(1)
        # self.page.query_selector('#main-pc-page-layout >> span.seller-main-badge >> span:text-is("退货补运费")').click()
        logger.info('跳转到【退货补运费】页面...')
        self.wait(self.page)
        for c in range(5):
            try:
                if self.page.query_selector('button:text-is("关闭"):visible') is not None:
                    self.page.query_selector('button:text-is("关闭"):visible').click(timeout=3000)
                    break
            except:
                pass
            time.sleep(1)
        for c in range(3):
            try:
                btn_list = self.page.query_selector_all('button:has-text("我知道了"):visible')
                for btn in btn_list:
                    btn.click()
            except:
                pass
            time.sleep(10)
        for i in range(20):
            try:
                if self.page.query_selector('div:text-is("服务记录"):visible') is not None:
                    break
            except:
                pass
            time.sleep(1)
            logger.info(f'等待页面加载【{i + 1}】秒...')
        time.sleep(3)
        if self.page.query_selector('div.FreightInsuranceGuideTitleV2:visible') is not None:
            logger.info('没有权限查询运费险')
            return '-'
        for c in range(5):
            try:
                if self.page.query_selector('div.kwaishop-seller-insurance-pc-modal:visible') is not None:
                    self.page.query_selector('span.kwaishop-seller-insurance-pc-modal-close-x:visible').click()
                    break
            except:
                pass
            time.sleep(1)
        time.sleep(2)
        self.page.query_selector('div:text-is("服务记录")').click()
        for i in range(20):
            try:
                if self.page.query_selector('label[title="生效时间"]:visible') is not None:
                    break
            except:
                pass
            time.sleep(1)
            logger.info(f'等待页面加载【{i + 1}】秒...')
        # self.page.query_selector('span:text-is("退货补运费服务记录")').click()
        time.sleep(0.5)
        for i in range(6):
            self.page.keyboard.press("ArrowDown")
            time.sleep(0.3)
        self.page.query_selector('input[placeholder="开始日期"]:visible').click()
        time.sleep(1)
        start_date = period + '-01'
        self.page.query_selector('input[placeholder="开始日期"]:visible').fill(f'{start_date} 00:00:00')
        time.sleep(1)
        self.page.query_selector('div.kwaishop-seller-insurance-pc-picker-dropdown:visible >> button:has-text("确 定")').click()
        time.sleep(1)
        self.page.query_selector('input[placeholder="结束日期"]:visible').click()
        time.sleep(1)
        end_date = ((datetime.datetime.strptime(start_date, '%Y-%m-%d') + datetime.timedelta(days=31)).replace(day=1) - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
        self.page.query_selector('input[placeholder="结束日期"]:visible').fill(f'{end_date} 23:59:59')
        time.sleep(1)
        self.page.query_selector('div.kwaishop-seller-insurance-pc-picker-dropdown:visible >> button:has-text("确 定")').click()
        time.sleep(1)
        logger.info('点击【查询】...')
        with self.page.expect_response('https://s.kwaixiaodian.com/gateway/privileges/insurance/b/pc/backend/listView') as response_info:
            self.page.query_selector('button:has-text("查 询")').click()
        response = response_info.value
        self.wait(self.page)
        if response.status != 200:
            logger.info('查询失败')
            raise Exception("查询失败")
        time.sleep(3)
        if self.page.query_selector('li.kwaishop-seller-insurance-pc-pagination-total-text') is None:
            logger.info('暂无数据')
            return 0
        page_text = self.page.query_selector('li.kwaishop-seller-insurance-pc-pagination-total-text').text_content()
        logger.info(page_text)
        total = page_text.split(' ')[1]
        return total

    def unzip(self, zip_path, extract_path):
        with zipfile.ZipFile(zip_path, 'r') as zip_ref:
            zip_ref.extractall(extract_path)

    def get_fund_flow_file(self, file_path, yesterday):
        # 删除旧文件
        path = os.path.join(self.bill_download_path, yesterday)
        file_list = []
        self.get_all_files(path, file_list)
        for file in file_list:
            os.remove(file)
        # 解压文件
        self.unzip(file_path, path)
        for file in os.listdir(path):
            if '_jdsc' not in file:
                return os.path.join(path, file)
        return None

    # 更新日志
    def update_log(self, log_id_list, message):
        data = {'logIdList': log_id_list, 'message': message}
        timestamp = int(time.time() * 1000)
        text = "{}{}{}".format(self.app_id, timestamp, self.secret)
        sign = hashlib.md5(text.encode(encoding='UTF-8')).hexdigest()
        url = self.host + f"api/v1/logRecord/updateLog?appId={self.app_id}&sign={sign.upper()}&timestamp={timestamp}"
        logger.info(f'url：{url}')
        logger.info(f'保存参数：{data}')
        res = requests.post(url, json=data)
        logger.info(f'保存结果：{res.text}')
        if res.status_code == 200:
            return res.json()['data']